package com.guodi.map.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.guodi.common.utils.ReadFileUtil;
import com.guodi.map.service.IGISServiceParser;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 解析 湖北金拓维 wms、wmts、wfs服务
 * @作者： 陈宏成
 * @日期： 2021/11/5
 */
@Service
public class HuBeiJinTuoWeiGISServiceImpl implements IGISServiceParser {

    /**
     * 支持的发布类型
     */
    private static String SUPPORTRELEASETYPE = "jintuowei";

    /**
     * 判断服务是否存在，wmts服务如果不加request参数，会报400错误，所以必须加上参数再请求
     * @入参： layerUrl 图层URL
     * @出参： true -- 服务存在，false -- 服务不存在
     * @作者： 陈宏成
     * @日期： 2021/11/8
     */
    public boolean isExist(String layerUrl){
        boolean existHttpURLConnection = ReadFileUtil.isExistHttpURLConnection(this.addParamToUrl(layerUrl));
        return existHttpURLConnection;
    }

    /**
     * 是否支持这种服务
     *
     * @param layerUrl    图层URL
     * @param releaseType 发布类型
     *
     * @return true -- 支持这种服务，false -- 不支持这种服务
     */
    @Override
    public boolean isSupport(String layerUrl, String releaseType) {
        return Objects.equals(SUPPORTRELEASETYPE, releaseType);
    }

    /**
     * 获取图层要素类型
     *
     * @param layerUrl    服务地址
     * @param layerTable  图层表
     * @param releaseType 发布类型
     *
     * @return 要素类型字典编号
     */
    @Override
    public String getFeatureTypeByUrlAndTable(String layerUrl, String layerTable, String releaseType) {
        // TODO: 2022/3/15 没实现
        return null;
    }

    /**
     * @入参： layerUrl 图层URL
     * @出参： releaseType 发布类型 WMS、WMTS
     * @作者： 陈宏成
     * @日期： 2021/11/5
     */
    public Map<String, Object> loadLayerTable(String layerUrl, String releaseType){
//        if(MapConst.MAP_SERVICE_TYPE_HBJTW.equals(releaseType) ){
            // 判断是否需要追加?request=getCapabilities&service=xxx
            layerUrl = addParamToUrl(layerUrl);
            // 2021-11-05 对接服务
            if (layerUrl.toLowerCase().contains("wms")) {
                String xmlContent = ReadFileUtil.getStringByUrl(layerUrl);
                return loadWms(xmlContent);
            }else if (layerUrl.toLowerCase().contains("wmts")) {
                String xmlContent = ReadFileUtil.getStringByUrl(layerUrl);
                return loadWmts(xmlContent);
            }
//        }
        throw new RuntimeException("服务不支持");
    }

    /**
     * 解析 湖北金拓维 wms 服务
     * @入参： xmlContent 图层URL返回的xml内容
     * @出参：
     * @作者： 陈宏成
     * @日期： 2021/11/5
     */
    private Map<String, Object> loadWms(String xmlContent){
        // 对url进行转义
        xmlContent = escapeAMP(xmlContent);
        Map<String, Object> resultMap = new HashMap<>();
        // 存储图层表名
        List<JSONObject> layerTableList = new ArrayList<JSONObject>();
        // 根据URL地址获取返回的XML文件字符串
        resultMap.put("loadType", "");
        resultMap.put("lods", "");
        try {
            // 解析xml
            Document document = DocumentHelper.parseText(xmlContent);
            Element rootElement = document.getRootElement();
            Element capability = rootElement.element("Capability");
            List<Element> layers = capability.element("Layer").elements("Layer");
            if(layers == null || layers.isEmpty()){
                throw  new RuntimeException( "服务地址有问题，请检查是否可用");
            }
            for(int i = 0; i < layers.size(); i++) {
                // 图层处理
                Element layer = layers.get(i);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("name",layer.elementText("Name"));
                jsonObject.put("id",layer.elementText("Name"));
                // 四至坐标和坐标系统
                List<Element> boundingBox = layer.elements("BoundingBox");
                for(Element box : boundingBox) {
                    String crs = box.attributeValue("SRS");
                    crs = StringUtils.isNotBlank(crs)? crs : box.attributeValue("CRS");
                    if (crs.toUpperCase().contains("EPSG")){
                        String wkid = crs.replace("EPSG:","");
                        String minx = box.attributeValue("minx");
                        String miny = box.attributeValue("miny");
                        String maxx = box.attributeValue("maxx");
                        String maxy = box.attributeValue("maxy");
                        String initialExtent = minx + "," + miny + "," + maxx + "," + maxy;
                        jsonObject.put("initialExtent", initialExtent);
                        jsonObject.put("wkid", wkid);
                        if (!resultMap.containsKey("wkid")){
                            resultMap.put("wkid", wkid);
                            resultMap.put("initialExtent", initialExtent);
                        }
                        break;
                    }
                }
                // 追加入列表
                layerTableList.add(jsonObject);
            }
            resultMap.put("layerTableList", layerTableList);
        } catch (DocumentException e) {
            e.printStackTrace();
            throw  new RuntimeException( "服务地址有问题，请检查是否可用");
        }
        return resultMap;
    }

    /**
     * 解析 湖北金拓维 WMTS 服务
     * @入参： xmlContent 图层URL返回的xml内容
     * @出参：
     * @作者： 陈宏成
     * @日期： 2021/11/5
     */
    private Map<String, Object> loadWmts(String xmlContent){
        // 对url进行转义
        xmlContent = escapeAMP(xmlContent);
        Map<String, Object> resultMap = new HashMap<>();
        // 存储图层表名
        List<JSONObject> layerTableList = new ArrayList<JSONObject>();
        // 根据URL地址获取返回的XML文件字符串
        resultMap.put("loadType", "");
        resultMap.put("lods", "");
        try {
            // 解析xml
            Document document = DocumentHelper.parseText(xmlContent);
            Element rootElement = document.getRootElement();
            Element contents = rootElement.element("Contents");
            List<Element> layers = contents.elements("Layer");
            if(layers == null || layers.isEmpty()){
                throw  new RuntimeException( "服务地址有问题，请检查是否可用");
            }
            for(int i = 0; i < layers.size(); i++) {
                // 图层处理
                Element layer = layers.get(i);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("name",layer.elementText("Identifier"));
                jsonObject.put("id",layer.elementText("Identifier"));
                // 四至坐标和坐标系统
                Element boundingBox = layers.get(0).element("WGS84BoundingBox");
                String lowerCorner = boundingBox.elementText("LowerCorner");
                String upperCorner = boundingBox.elementText("UpperCorner");
                Element tileMatrixSetLink = layer.element("TileMatrixSetLink");
                Element tileMatrixSet = tileMatrixSetLink.element("TileMatrixSet");
                jsonObject.put("tileMatrixSet",tileMatrixSet.getText());
                String[] lowerCornerArr = lowerCorner.split(" ");
                String[] upperCornerArr = upperCorner.split(" ");
                String minx = lowerCornerArr[0];
                String miny = lowerCornerArr[1];
                String maxx = upperCornerArr[0];
                String maxy = upperCornerArr[1];
                String initialExtent = minx + "," + miny + "," + maxx + "," + maxy;
                jsonObject.put("initialExtent", initialExtent);
                if (!resultMap.containsKey("initialExtent")){
                    resultMap.put("initialExtent", initialExtent);
                }
                // 追加入列表
                layerTableList.add(jsonObject);
            }
            resultMap.put("wkid", "4490");
            resultMap.put("layerTableList", layerTableList);
        } catch (DocumentException e) {
            e.printStackTrace();
            throw  new RuntimeException( "服务地址有问题，请检查是否可用");
        }
        return resultMap;
    }

    /**
     * 将xml中的 & 转成 &amp;
     * @入参：
     * @出参：
     * @作者： 陈宏成
     * @日期： 2021/11/5
     */
    private String escapeAMP(String xml){
        StringBuilder sb = new StringBuilder(xml);
        int fromIndex = 0;
        int currentIndex = -1;
        while ((currentIndex = sb.indexOf("&", fromIndex)) != -1){
            String str = sb.substring(currentIndex, currentIndex + 5);
            if (!"&amp;".equals(str)){
                // 未被转义，就进行转义
                sb.deleteCharAt(currentIndex);
                sb.insert(currentIndex, "&amp;");
            }
            // 已被转义了，就直接跳过
            fromIndex = currentIndex + 5;
        }
        return sb.toString();
    }

    /**
     * 为图层url追加参数 request=getCapabilities&service=xxx
     * @入参： layerUrl 图层URL
     * @出参： 例如：http://10.1.6.36:8088/geoserver/geoserverdata/wms?request=getCapabilities&service=wms
     * @作者： 陈宏成
     * @日期： 2021/11/8
     */
    private String addParamToUrl(String layerUrl){
        // 获取服务类型
        String serviceType = null;
        if (layerUrl.toLowerCase().contains("wms")) {
            serviceType = "wms";
        }else if (layerUrl.toLowerCase().contains("wmts")) {
            serviceType = "wmts";
        }else {
            throw new RuntimeException("服务不支持");
        }
        // 判断是否有参数
        if (!layerUrl.contains("?")){
            // 没有参数，直接拼接
            layerUrl += "?request=getCapabilities&service=" + serviceType;
        }else{
            // 已有参数
            // 判断是否包含request和service这两个参数
            if (!layerUrl.contains("request")){
                layerUrl += layerUrl.endsWith("?")? "": "&" + "request=getCapabilities";
            }
            if (!layerUrl.contains("service")){
                layerUrl += layerUrl.endsWith("?")? "": "&" + "service=" + serviceType;
            }
        }
        return layerUrl;
    }
}
